package com.aco.fatureapp.service;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import org.apache.http.NameValuePair;
import org.json.JSONObject;

import android.content.Context;
import android.content.SharedPreferences;
import br.com.ac.fatureweb.integration.model.LeituristaVO;

import com.aco.fatureapp.model.AccessLog;
import com.aco.fatureapp.model.AccessLog.TypeAction;
import com.aco.fatureapp.model.ConfiguracaoApp;
import com.aco.fatureapp.model.Leiturista;
import com.aco.fatureapp.utilitary.DataUtils;
import com.aco.fatureapp.utilitary.JSonHttpRequest;
import com.aco.fatureapp.utilitary.JSonHttpRequest.EnumTipoRequisicao;
import com.aco.fatureapp.utilitary.Utils;
import com.google.gson.Gson;
import com.google.inject.Inject;
import com.orm.SugarRecord;
import com.orm.query.Select;

public class SrvAccess {

	private static final String ERROR_CREDENCIAIS = "Credenciais informadas são inválidas.";

	private static final String LOGADO = "logado";

	private static final String STATUS = "status";

	private static final String FLG_ATUALIZADA_SENHA = "flgAtualizadaSenha";

	private static final String DATA_GERACAO_SENHA = "dataGeracaoSenha";

	private static final String SENHA = "senha";

	private static final String ENUM_TIPO = "enumTipo";

	private static final String NOME = "nome";

	private static final String CODIGO = "codigo";

	private static final String ID = "id";

	private static final int DIAS_LOGIN = 55;

	private List<NameValuePair> mParams = new ArrayList<NameValuePair>();

	private JSonHttpRequest mJsonRequest = null;

	@Inject
	public SrvAccess() {
		super();

		// mDatabase = new SugarDb(SugarApp.getSugarContext())
		// .getWritableDatabase();

		this.mJsonRequest = new JSonHttpRequest();
	}

	public AccessLog isConfigurationOk() {
		final Iterator<ConfiguracaoApp> lstConfiguracao = SugarRecord
				.findAll(ConfiguracaoApp.class);

		if (lstConfiguracao == null || !lstConfiguracao.hasNext()) {

			return new AccessLog(TypeAction.CONFIGURATION,
					"É necessário preencher a configuração do App.");
		}

		return null;
	}

	public AccessLog validateLogin(String login, String senha, String imei) {
		try {
			// Verificar se já constar no equipamento o login informado.
			Leiturista leituristaPer = Select.from(Leiturista.class)
					.where("CODIGO = ?", new String[] { login }).first();

			// Se existir validar a senha do mesmo e verificar a necessidade de
			// atualizar seus dados no aparelho.
			if (leituristaPer != null) {

				// Mais de quinze dias buscar remoto.
				if (validateAccessMore15Days(leituristaPer)) {
					return getUserRemote(login, senha, imei);
				}
				String encryptMd5 = Utils.encryptMd5(senha);

				if (!leituristaPer.getSenha().equalsIgnoreCase(encryptMd5)) {
					return new AccessLog(TypeAction.ERROR, ERROR_CREDENCIAIS);
				}

				return new AccessLog(TypeAction.LOGIN, null, leituristaPer);
			}
			// Se não existe o login local buscar no serviço remoto e gravar
			// local, para ser validar no próximo acesso.
			return getUserRemote(login, senha, imei);
		}
		catch (Exception ex) {
			return new AccessLog(TypeAction.ERROR, ERROR_CREDENCIAIS
					+ "\nDetalhes: " + ex.getMessage());
		}
	}

	@SuppressWarnings("unchecked")
	private AccessLog getUserRemote(String login, String senha, String imei)
			throws Exception {
		if (!JSonHttpRequest
				.webServiceIsAvailable(JSonHttpRequest.REQUEST_TYPE_ACCESS)) {
			return new AccessLog(TypeAction.ERROR,
					JSonHttpRequest.SERVICO_INDISPONIVEL);
		}

		mParams = Utils.getDefaultParams(login, senha, imei);

		List<JSONObject> userJson = (List<JSONObject>) mJsonRequest.execute(
				JSonHttpRequest.getAccessURL() + "buscarUsuarioMobile",
				EnumTipoRequisicao.POST, mParams);

		if (userJson != null) {
			LeituristaVO leituristaVO = new Gson().fromJson(userJson.iterator()
					.next().toString(), LeituristaVO.class);

			Leiturista leiturista = new Leiturista(leituristaVO);
			leiturista.setDataGeracaoSenha(new Date().getTime());

			leiturista.save();

			return new AccessLog(TypeAction.LOGIN, null, leiturista);
		}

		return new AccessLog(TypeAction.ERROR, ERROR_CREDENCIAIS);
	}

	private boolean validateAccessMore15Days(Leiturista leiturista) {

		Calendar calendar = Calendar.getInstance(new Locale("pt", "BR"));

		calendar.setTimeInMillis(leiturista.getDataGeracaoSenha());

		int diasAcesso = DataUtils.getDiferencaEmDias(new Date(),
				calendar.getTime());

		// Se tiver com mais de quinze dias buscar os dados do usuário no
		// serviço remoto.
		if (diasAcesso > DIAS_LOGIN) {

			Leiturista findLeiturista = SugarRecord.findById(Leiturista.class,
					leiturista.getId());

			findLeiturista.delete();

			return true;
		}

		return false;
	}

	public static void login(final Context ctx, final Leiturista usuario,
			final String chave) {
		final SharedPreferences settings = ctx.getSharedPreferences(chave, 0);

		final SharedPreferences.Editor editor = settings.edit();

		if (usuario.getId() != null) {
			editor.putLong(ID, usuario.getId());
		}

		editor.putLong(CODIGO, usuario.getCodigo());

		editor.putString(NOME, usuario.getNome());

		editor.putInt(ENUM_TIPO, usuario.getEnumTipoCadastrador());

		editor.putString(SENHA, usuario.getSenha());

		editor.putLong(DATA_GERACAO_SENHA, usuario.getDataGeracaoSenha());

		editor.putBoolean(FLG_ATUALIZADA_SENHA, usuario.getFlgAtualizaSenha());

		editor.putInt(STATUS, usuario.getStatus());

		editor.putBoolean(LOGADO, true);

		editor.commit();
	}

	public static Leiturista getUsuarioLogado(final Context ctx,
			final String chave) {
		final SharedPreferences preferences = ctx
				.getSharedPreferences(chave, 0);

		if (preferences.getBoolean(LOGADO, false)) {

			final Leiturista user = new Leiturista();

			user.setId(preferences.getLong(ID, 0));

			user.setCodigo(preferences.getLong(CODIGO, 0));

			user.setNome(preferences.getString(NOME, ""));

			user.setEnumTipoCadastrador(preferences.getInt(ENUM_TIPO, 0));

			user.setSenha(preferences.getString(SENHA, ""));

			user.setDataGeracaoSenha(preferences.getLong(DATA_GERACAO_SENHA, 0));

			user.setFlgAtualizaSenha(preferences.getBoolean(
					FLG_ATUALIZADA_SENHA, false));

			user.setStatus(preferences.getInt(STATUS, 0));

			user.setLogado(preferences.getBoolean(LOGADO, false));

			return user;
		}

		return null;
	}
}
